

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>ALASpy.pointDataRecords &mdash; ALASpy 0.1.1 documentation</title>
    
    <link rel="stylesheet" href="../../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
    
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../../',
        VERSION:     '0.1.1',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../_static/underscore.js"></script>
    <script type="text/javascript" src="../../_static/doctools.js"></script>
    <script type="text/javascript" src="../../_static/sidebar.js"></script>
    <link rel="top" title="ALASpy 0.1.1 documentation" href="../../index.html" />
    <link rel="up" title="Module code" href="../index.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li><a href="../../index.html">ALASpy 0.1.1 documentation</a> &raquo;</li>
          <li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <h1>Source code for ALASpy.pointDataRecords</h1><div class="highlight"><pre>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot; The LAS Object PointDataRecords module.</span>

<span class="sd">  :Author:</span>
<span class="sd">    - 2010-2012 Nicola Creati and Roberto Vidmar</span>

<span class="sd">  :Revision:  $Revision: 2 $</span>
<span class="sd">              $Date: 2012-10-22 15:55:02 +0200 (Mon, 22 Oct 2012) $</span>

<span class="sd">  :Copyright: 2010-2012</span>
<span class="sd">              Nicola Creati &lt;ncreati@inogs.it&gt;</span>
<span class="sd">              Roberto Vidmar &lt;rvidmar@inogs.it&gt;</span>

<span class="sd">  :License: MIT/X11 License (see :download:`LICENSE.txt</span>
<span class="sd">                             &lt;../../LICENSE.txt&gt;`)</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">import</span> <span class="nn">numexpr</span> <span class="kn">as</span> <span class="nn">ne</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="kn">as</span> <span class="nn">np</span>

<span class="c"># Local imports</span>
<span class="kn">from</span> <span class="nn">header</span> <span class="kn">import</span> <span class="n">PointDataRecord</span>
<span class="kn">from</span> <span class="nn">lasExceptions</span> <span class="kn">import</span> <span class="p">(</span><span class="n">FileCreationError</span><span class="p">,</span> <span class="n">InvalidPointDataFormatID</span><span class="p">,</span>
  <span class="n">MandatoryFieldMissing</span><span class="p">,</span> <span class="n">UnimplementedException</span><span class="p">)</span>

<span class="c"># Functions:</span>
<div class="viewcode-block" id="sumLists"><a class="viewcode-back" href="../../ALASpy.html#ALASpy.pointDataRecords.sumLists">[docs]</a><span class="k">def</span> <span class="nf">sumLists</span><span class="p">(</span><span class="n">l1</span><span class="p">,</span> <span class="n">l2</span><span class="p">):</span>
  <span class="sd">&quot;&quot;&quot; Return element by element sum of the two lists</span>

<span class="sd">    :param l1: fisrt list to add</span>
<span class="sd">    :type  l1: list</span>
<span class="sd">    :param l2: second list to add</span>
<span class="sd">    :type  l2: list</span>
<span class="sd">    :returns: element by element sum of l1 and l2</span>
<span class="sd">    :rtype: list</span>

<span class="sd">    .. warning:: the returned list will have the same number of elements of the</span>
<span class="sd">       shortest one</span>
<span class="sd">  &quot;&quot;&quot;</span>
  <span class="k">return</span> <span class="nb">map</span><span class="p">(</span><span class="nb">sum</span><span class="p">,</span> <span class="nb">zip</span><span class="p">(</span><span class="n">l1</span><span class="p">,</span> <span class="n">l2</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="checkForMandatoryFields"><a class="viewcode-back" href="../../ALASpy.html#ALASpy.pointDataRecords.checkForMandatoryFields">[docs]</a><span class="k">def</span> <span class="nf">checkForMandatoryFields</span><span class="p">(</span><span class="n">points</span><span class="p">):</span>
  <span class="sd">&quot;&quot;&quot; Check if points object has the right structure</span>

<span class="sd">    :param points: object</span>
<span class="sd">    :type  points: :class:`dict`, :class:`numpy.ndarray`, :class:`numpy.memmap`</span>
<span class="sd">    :raises: :class:`~ALASpy.lasExceptions.MandatoryFieldMissing`</span>
<span class="sd">  &quot;&quot;&quot;</span>
  <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">points</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
    <span class="n">missingFields</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="s">&quot;XYZ&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">points</span><span class="o">.</span><span class="n">keys</span><span class="p">()))</span>

  <span class="k">else</span><span class="p">:</span>
    <span class="n">missingFields</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="s">&quot;XYZ&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">points</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">names</span><span class="p">))</span>

  <span class="k">if</span> <span class="n">missingFields</span><span class="p">:</span>
    <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span><span class="s">&quot;Mandatory field(s) </span><span class="si">%s</span><span class="s"> missing in points.&quot;</span> <span class="o">%</span>
      <span class="nb">str</span><span class="p">(</span><span class="nb">tuple</span><span class="p">(</span><span class="n">missingFields</span><span class="p">)))</span>
    <span class="k">raise</span> <span class="n">MandatoryFieldMissing</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="hasGPSTime"><a class="viewcode-back" href="../../ALASpy.html#ALASpy.pointDataRecords.hasGPSTime">[docs]</a><span class="k">def</span> <span class="nf">hasGPSTime</span><span class="p">(</span><span class="n">points</span><span class="p">):</span>
  <span class="sd">&quot;&quot;&quot; Return True if points object has GPSTime field</span>

<span class="sd">    :param points: object</span>
<span class="sd">    :type  points: :class:`dict`, :class:`numpy.ndarray`, :class:`numpy.memmap`</span>
<span class="sd">    :returns: True if points object has GPSTime field</span>
<span class="sd">    :rtype: bool</span>
<span class="sd">  &quot;&quot;&quot;</span>
  <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">points</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
    <span class="n">missingFields</span> <span class="o">=</span> <span class="nb">set</span><span class="p">((</span><span class="s">&#39;GPStime&#39;</span><span class="p">,</span> <span class="p">))</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">points</span><span class="o">.</span><span class="n">keys</span><span class="p">()))</span>
  <span class="k">else</span><span class="p">:</span>
    <span class="n">missingFields</span> <span class="o">=</span> <span class="nb">set</span><span class="p">((</span><span class="s">&#39;GPSTime&#39;</span><span class="p">,</span> <span class="p">))</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">points</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">names</span><span class="p">))</span>

  <span class="k">if</span> <span class="n">missingFields</span><span class="p">:</span>
    <span class="k">return</span> <span class="bp">False</span>
  <span class="k">else</span><span class="p">:</span>
    <span class="k">return</span> <span class="bp">True</span>

<span class="c">#===============================================================================</span></div>
<div class="viewcode-block" id="PointDataRecords"><a class="viewcode-back" href="../../ALASpy.html#ALASpy.pointDataRecords.PointDataRecords">[docs]</a><span class="k">class</span> <span class="nc">PointDataRecords</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
  <span class="sd">&quot;&quot;&quot; The Point Data Records object class</span>
<span class="sd">  &quot;&quot;&quot;</span>
<div class="viewcode-block" id="PointDataRecords.__init__"><a class="viewcode-back" href="../../ALASpy.html#ALASpy.pointDataRecords.PointDataRecords.__init__">[docs]</a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parent</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Create a new instance of the WHOLE dataset</span>

<span class="sd">      :param parent: LasObject</span>
<span class="sd">      :type parent: :class:`~ALASpy.las.LasObject`</span>

<span class="sd">      .. note:: No memory will be allocated yet</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span> <span class="o">=</span> <span class="n">parent</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_header</span> <span class="o">=</span> <span class="n">parent</span><span class="o">.</span><span class="n">header</span><span class="p">()</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_stopped</span> <span class="o">=</span> <span class="bp">False</span>    <span class="c"># is it necessary? Ask Nik.</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_mapFile</span> <span class="o">=</span> <span class="bp">None</span>     <span class="c"># Memory mapped array</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_removedRecords</span> <span class="o">=</span> <span class="bp">None</span> <span class="c"># Number of records removed while reading</span>
</div>
<div class="viewcode-block" id="PointDataRecords.__repr__"><a class="viewcode-back" href="../../ALASpy.html#ALASpy.pointDataRecords.PointDataRecords.__repr__">[docs]</a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="n">cname</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span>
    <span class="n">s</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s"> container opened for &quot;</span> <span class="o">%</span> <span class="n">cname</span>
    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span><span class="o">.</span><span class="n">isReadMode</span><span class="p">():</span>
      <span class="n">s</span> <span class="o">+=</span> <span class="s">&quot;reading:</span><span class="se">\n</span><span class="s">&quot;</span>
      <span class="n">s</span> <span class="o">+=</span> <span class="p">(</span><span class="s">&quot;Records can be returned in a Python container using the</span><span class="se">\n</span><span class="s">&quot;</span>
        <span class="s">&quot;</span><span class="si">%s</span><span class="s">().read() method or with usual indexing:</span><span class="se">\n</span><span class="s">&quot;</span>
        <span class="s">&quot;i.e. </span><span class="si">%s</span><span class="s">()[i]&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">cname</span><span class="p">,</span> <span class="n">cname</span><span class="p">))</span>
    <span class="k">else</span><span class="p">:</span>
      <span class="n">s</span> <span class="o">+=</span> <span class="s">&quot;writing:</span><span class="se">\n</span><span class="s">&quot;</span>
      <span class="n">s</span> <span class="o">+=</span> <span class="p">(</span><span class="s">&quot;Records can be written to file using the</span><span class="se">\n</span><span class="s">&quot;</span>
        <span class="s">&quot;</span><span class="si">%s</span><span class="s">().write() method&quot;</span> <span class="o">%</span> <span class="n">cname</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">s</span>
</div>
<div class="viewcode-block" id="PointDataRecords.__getitem__"><a class="viewcode-back" href="../../ALASpy.html#ALASpy.pointDataRecords.PointDataRecords.__getitem__">[docs]</a>  <span class="k">def</span> <span class="nf">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">index</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Return PointDataRecord at index</span>

<span class="sd">      :param index: index of point to retrieve</span>
<span class="sd">      :type index: int</span>
<span class="sd">      :returns: PointDataRecord instance at index</span>
<span class="sd">      :rtype: :class:`~ALASpy.header.PointDataRecord`</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">isReadMode</span><span class="p">():</span>
      <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s"> not opened for reading&quot;</span> <span class="o">%</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">fid</span><span class="p">()</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span>
      <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">getOffsetToPointData</span><span class="p">()</span> <span class="o">+</span>
      <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">getPointDataReclen</span><span class="p">()</span> <span class="o">*</span> <span class="n">index</span><span class="p">)</span>
    <span class="n">point</span> <span class="o">=</span> <span class="n">PointDataRecord</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="p">,</span> <span class="n">index</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">point</span>
</div>
  <span class="k">def</span> <span class="nf">_makeDtypes</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fields</span><span class="p">,</span> <span class="n">asFloat</span><span class="p">,</span> <span class="n">withGPS</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Return dtype both for input and output</span>

<span class="sd">      :param fields: List or tuple of field names (strings) from</span>
<span class="sd">                     header pointDataRecordDtype() method</span>
<span class="sd">                     or: the string &#39;all&#39;</span>
<span class="sd">                     or: the string &#39;short&#39;, shortcut for</span>
<span class="sd">                       (X(f4),Y(f4),Z(f4),Intensity, Classification)</span>
<span class="sd">                       In this case only (X, Y, Z, Intensity, Classification)</span>
<span class="sd">                       will be returned. If offset parameter is not None</span>
<span class="sd">                       X, Y, Z values returned will be float32</span>
<span class="sd">      :type  fields: tuple or string</span>
<span class="sd">      :param asFloat: generate dtype float instead of double for X, Y, Z</span>
<span class="sd">      :type  asFloat: bool</span>
<span class="sd">      :param withGPS: generate dtype with GPSTime field</span>
<span class="sd">      :type  withGPS: bool</span>
<span class="sd">      :returns: inputDtype, outputDtype</span>
<span class="sd">      :rtype: tuple of numpy.dtype</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">fields</span> <span class="ow">in</span> <span class="p">(</span><span class="s">&#39;all&#39;</span><span class="p">,</span> <span class="s">&#39;short&#39;</span><span class="p">):</span>
      <span class="n">inputDtype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">pointDataRecordDtype</span><span class="p">(</span><span class="s">&#39;all&#39;</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
      <span class="n">inputDtype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">pointDataRecordDtype</span><span class="p">(</span><span class="n">fields</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">fields</span> <span class="o">==</span> <span class="s">&#39;short&#39;</span><span class="p">:</span>
      <span class="c"># Short output, we don&#39;t care about all fields...</span>
      <span class="k">if</span> <span class="n">asFloat</span><span class="p">:</span>
        <span class="n">floatFormat</span> <span class="o">=</span> <span class="s">&#39;&lt;f4&#39;</span>
      <span class="k">else</span><span class="p">:</span>
        <span class="n">floatFormat</span> <span class="o">=</span> <span class="s">&#39;&lt;f8&#39;</span>
      <span class="n">outputDtype</span> <span class="o">=</span> <span class="p">[(</span><span class="s">&#39;X&#39;</span><span class="p">,</span> <span class="n">floatFormat</span><span class="p">),</span> <span class="p">(</span><span class="s">&#39;Y&#39;</span><span class="p">,</span> <span class="n">floatFormat</span><span class="p">),</span> <span class="p">(</span><span class="s">&#39;Z&#39;</span><span class="p">,</span> <span class="n">floatFormat</span><span class="p">),</span>
        <span class="p">(</span><span class="s">&#39;Intensity&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;u2&#39;</span><span class="p">),</span> <span class="p">(</span><span class="s">&#39;Classification&#39;</span><span class="p">,</span> <span class="s">&#39;|u1&#39;</span><span class="p">)]</span>
      <span class="k">if</span> <span class="n">withGPS</span><span class="p">:</span>
        <span class="n">outputDtype</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="s">&#39;GPSTime&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;f8&#39;</span><span class="p">))</span>
      <span class="n">outputDtype</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">dtype</span><span class="p">(</span><span class="n">outputDtype</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
      <span class="n">descr</span> <span class="o">=</span> <span class="n">inputDtype</span><span class="o">.</span><span class="n">descr</span>
      <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">f</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">descr</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">f</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="nb">set</span><span class="p">(</span><span class="s">&quot;XYZ&quot;</span><span class="p">):</span>
          <span class="n">descr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">f</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="s">&#39;&lt;f8&#39;</span><span class="p">)</span>
      <span class="n">outputDtype</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">dtype</span><span class="p">(</span><span class="n">descr</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">inputDtype</span><span class="p">,</span> <span class="n">outputDtype</span>

  <span class="k">def</span> <span class="nf">_rescaleXYZ</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">offsets</span><span class="p">,</span> <span class="n">asFloat</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Rescale x, y, z fields in data to their original value,</span>
<span class="sd">        *subtracting* optionally offset tuple from x and y.</span>

<span class="sd">      :param data: dataset to rescale</span>
<span class="sd">      :type  data: numpy.ndarray</span>
<span class="sd">      :param offsets: Offsets tuple to apply to data.</span>
<span class="sd">                      These value will be *subtracted*</span>
<span class="sd">                      New x = x - offsets[0], New y = y - offsets[1]</span>
<span class="sd">                      (default is to apply offsets from Header)</span>
<span class="sd">      :type  offsets: tuple</span>
<span class="sd">      :param asFloat: generate dtype float instead of double for X, Y, Z</span>
<span class="sd">      :type  asFloat: bool</span>
<span class="sd">      :returns: xyz tuple</span>
<span class="sd">      :rtype: tuple</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="c"># Get scales from Header</span>
    <span class="n">scales</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">scaleFactors</span><span class="p">()</span>
    <span class="c"># Do not move zero</span>
    <span class="n">zeros</span> <span class="o">=</span> <span class="p">(</span><span class="mf">0.</span><span class="p">,</span> <span class="mf">0.</span><span class="p">,</span> <span class="mf">0.</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">offsets</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
      <span class="c"># Get offsets from Header</span>
      <span class="n">offsets</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">offsets</span><span class="p">()</span>
      <span class="k">if</span> <span class="n">asFloat</span><span class="p">:</span>
        <span class="n">zeros</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">getXmin</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">getYmin</span><span class="p">(),</span> <span class="mi">0</span><span class="p">)</span>

    <span class="n">xyz</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">()</span>
    <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">scale</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">zero</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="s">&quot;XYZ&quot;</span><span class="p">,</span> <span class="n">scales</span><span class="p">,</span> <span class="n">offsets</span><span class="p">,</span> <span class="n">zeros</span><span class="p">):</span>
      <span class="n">xyz</span> <span class="o">+=</span> <span class="p">(</span><span class="n">ne</span><span class="o">.</span><span class="n">evaluate</span><span class="p">(</span><span class="s">&#39;((c * scale) + offset) - min&#39;</span><span class="p">,</span> <span class="n">local_dict</span><span class="o">=</span><span class="nb">dict</span><span class="p">(</span>
        <span class="n">c</span><span class="o">=</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">scale</span><span class="o">=</span><span class="n">scale</span><span class="p">,</span> <span class="n">offset</span><span class="o">=</span><span class="n">offset</span><span class="p">,</span> <span class="nb">min</span><span class="o">=</span><span class="n">zero</span><span class="p">)),</span> <span class="p">)</span>
    <span class="k">return</span> <span class="n">xyz</span>

  <span class="k">def</span>  <span class="nf">_data2points</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">totalRecsRead</span><span class="p">,</span> <span class="n">xyz</span><span class="p">,</span> <span class="n">points</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Move data to final destination</span>

<span class="sd">      :param data: dataset to rescale</span>
<span class="sd">      :type  data: numpy.ndarray</span>
<span class="sd">      :param totalRecsRead: total number of records read</span>
<span class="sd">      :type  totalRecsRead: int</span>
<span class="sd">      :param xyz: xyz tuple</span>
<span class="sd">      :type  xyz: tuple</span>
<span class="sd">      :param points: points object</span>
<span class="sd">      :type  points: dict, numpy.array or numpy.memmap</span>
<span class="sd">      :returns: points object</span>
<span class="sd">      :rtype: unchanged: dict, numpy.array or numpy.memmap</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="c">#-----------------------------------------------------------------------</span>
    <span class="k">def</span> <span class="nf">getData</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
      <span class="sd">&quot;&quot;&quot; Return the array for field name `n` of the data object</span>
<span class="sd">          or a zero filled array of the same size if data has no field `n`</span>
<span class="sd">      &quot;&quot;&quot;</span>
      <span class="k">if</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">data</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">names</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">data</span><span class="p">[</span><span class="n">n</span><span class="p">]</span>
      <span class="k">else</span><span class="p">:</span>
        <span class="n">nDtype</span> <span class="o">=</span> <span class="p">[</span><span class="n">f</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">points</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">descr</span> <span class="k">if</span> <span class="n">f</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="n">n</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
        <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span><span class="n">shape</span><span class="o">=</span><span class="n">data</span><span class="p">[</span><span class="s">&#39;X&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">shape</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">nDtype</span><span class="p">)</span>
    <span class="c">#-----------------------------------------------------------------------</span>
    <span class="n">recsValid</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
    <span class="n">xyzSet</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="s">&quot;XYZ&quot;</span><span class="p">)</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">points</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
      <span class="k">if</span> <span class="ow">not</span> <span class="n">points</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="s">&#39;X&#39;</span><span class="p">):</span>
        <span class="c"># dict is empty!</span>
        <span class="k">for</span> <span class="n">c</span><span class="p">,</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">xyz</span><span class="p">,</span> <span class="s">&quot;XYZ&quot;</span><span class="p">):</span>
          <span class="n">points</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">points</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">fields</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">type</span><span class="p">)</span>
        <span class="c"># Move remaining fields</span>
        <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">set</span><span class="p">(</span><span class="n">points</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">names</span><span class="p">)</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">xyzSet</span><span class="p">):</span>
          <span class="k">if</span> <span class="n">n</span> <span class="o">==</span> <span class="s">&#39;Classification&#39;</span><span class="p">:</span>
            <span class="n">points</span><span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="o">=</span> <span class="n">getData</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mi">0</span><span class="n">b11111</span>
          <span class="k">elif</span> <span class="p">(</span><span class="n">n</span> <span class="o">==</span> <span class="s">&#39;GPSTime&#39;</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">getVersionMinor</span><span class="p">()</span> <span class="o">==</span> <span class="mi">2</span><span class="p">):</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">getGlobalEncoding</span><span class="p">()</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
              <span class="n">points</span><span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="o">=</span> <span class="n">getData</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="o">-</span> <span class="mf">1E9</span>
          <span class="k">else</span><span class="p">:</span>
            <span class="n">points</span><span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="o">=</span> <span class="n">getData</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
      <span class="k">else</span><span class="p">:</span>
        <span class="c"># dict initialized</span>
        <span class="k">for</span> <span class="n">c</span><span class="p">,</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">xyz</span><span class="p">,</span> <span class="s">&quot;XYZ&quot;</span><span class="p">):</span>
          <span class="n">points</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">points</span><span class="p">[</span><span class="n">i</span><span class="p">],</span>
            <span class="n">c</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">points</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">fields</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">type</span><span class="p">))</span>

        <span class="c"># Move remaining fields</span>
        <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">set</span><span class="p">(</span><span class="n">points</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">names</span><span class="p">)</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">xyzSet</span><span class="p">):</span>
          <span class="n">points</span><span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">points</span><span class="p">[</span><span class="n">n</span><span class="p">],</span> <span class="n">getData</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
    <span class="k">else</span><span class="p">:</span>
      <span class="c"># No dict, ndarray or mmaped array</span>
      <span class="k">for</span> <span class="n">c</span><span class="p">,</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">xyz</span><span class="p">,</span> <span class="s">&quot;XYZ&quot;</span><span class="p">):</span>
        <span class="n">points</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">totalRecsRead</span><span class="p">:</span> <span class="n">totalRecsRead</span> <span class="o">+</span> <span class="n">recsValid</span><span class="p">]</span> <span class="o">=</span> <span class="n">c</span>
      <span class="c"># Copy remaining fields</span>
      <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">set</span><span class="p">(</span><span class="n">points</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">names</span><span class="p">)</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">xyzSet</span><span class="p">):</span>
        <span class="n">points</span><span class="p">[</span><span class="n">n</span><span class="p">][</span><span class="n">totalRecsRead</span><span class="p">:</span> <span class="n">totalRecsRead</span> <span class="o">+</span> <span class="n">recsValid</span><span class="p">]</span> <span class="o">=</span> <span class="n">getData</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">points</span>

<span class="c">#-------------------------------------------------------------------------------</span>
<span class="c"># Public methods</span>
<span class="c">#-------------------------------------------------------------------------------</span>
<div class="viewcode-block" id="PointDataRecords.read"><a class="viewcode-back" href="../../ALASpy.html#ALASpy.pointDataRecords.PointDataRecords.read">[docs]</a>  <span class="k">def</span> <span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">recStart</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">recEnd</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">skip</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">recsPerChunk</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
    <span class="n">offsets</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">fields</span><span class="o">=</span><span class="s">&#39;all&#39;</span><span class="p">,</span> <span class="n">unique</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">withGPS</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">pointsDtype</span><span class="o">=</span><span class="nb">dict</span><span class="p">,</span>
    <span class="n">asFloat</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Read all points and return a Python container according to</span>
<span class="sd">        `pointsDtype`</span>

<span class="sd">      :param recStart: Record number to start from (default 0)</span>
<span class="sd">      :type  recStart: int</span>
<span class="sd">      :param recEnd: Last record to read,  default is -1, the number of</span>
<span class="sd">                     records from the header</span>
<span class="sd">      :type  recEnd: int</span>
<span class="sd">      :param skip: Integer number of records to skip while reading</span>
<span class="sd">      :type  skip: int</span>
<span class="sd">      :param recsPerChunk: Read file in recsPerChunk chunks</span>
<span class="sd">      :type  recsPerChunk: int</span>
<span class="sd">      :param offsets: Offsets tuple to apply to data.</span>
<span class="sd">                      These value will be *subtracted*</span>
<span class="sd">                      New x = x - offsets[0], New y = y - offsets[1]</span>
<span class="sd">                      (default is to apply offsets from Header)</span>
<span class="sd">      :type  offsets: tuple</span>
<span class="sd">      :param fields: * List or tuple of field names (strings) from</span>
<span class="sd">                       header pointDataRecordDtype() method or:</span>
<span class="sd">                     * the string &#39;all&#39; or:</span>
<span class="sd">                     * the string &#39;short&#39;, shortcut for</span>
<span class="sd">                       (X(f4), Y(f4), Z(f4), Intensity, Classification)</span>
<span class="sd">                       In this case only (X, Y, Z, Intensity, Classification)</span>
<span class="sd">                       will be returned. If offset parameter is not None</span>
<span class="sd">                       X, Y, Z values returned will be float32</span>
<span class="sd">      :type  fields: tuple or string</span>
<span class="sd">      :param unique: If True remove duplicate data points (only for numpy</span>
<span class="sd">                     objects)</span>
<span class="sd">      :type  unique: bool</span>
<span class="sd">      :param withGPS: If True adds GPS data to short output</span>
<span class="sd">      :type  withGPS: bool</span>
<span class="sd">      :param pointsDtype: Points will be saved according to argument type:</span>

<span class="sd">       * :class:`dict`        -&gt; Python dictionary</span>
<span class="sd">       * :class:`numpy.array` -&gt; numpy ndarray</span>
<span class="sd">       * :class:`string`      -&gt; numpy memory mapped array</span>
<span class="sd">         file name</span>
<span class="sd">      :type  pointsDtype: :class:`dict`, :class:`numpy.array` or :class:`string`</span>
<span class="sd">      :param asFloat: if True output format of X, Y, Z fields will be float (f4)</span>
<span class="sd">                      instead of double (f8).</span>
<span class="sd">                      In this case an offset of None means that offset will be</span>
<span class="sd">                      computed from Header xmin, ymin, zmin</span>
<span class="sd">      :type  asFloat: bool</span>
<span class="sd">      :raises: :class:`~ALASpy.lasExceptions.FileCreationError`,</span>
<span class="sd">               :class:`~ALASpy.lasExceptions.UnimplementedException`,</span>
<span class="sd">               :class:`IOError`</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">isReadMode</span><span class="p">():</span>
      <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s"> not opened for reading&quot;</span> <span class="o">%</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">)</span>

    <span class="c"># If the point data format is not 1.1 or 1.3 GPS field</span>
    <span class="c"># is missing from records</span>
    <span class="k">if</span> <span class="n">withGPS</span> <span class="ow">and</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">getPointDataFormatID</span><span class="p">()</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">)):</span>
      <span class="n">withGPS</span> <span class="o">=</span> <span class="bp">False</span>
    <span class="c"># Create data types for reading and saving points</span>
    <span class="n">inputDtype</span><span class="p">,</span> <span class="n">outputDtype</span> <span class="o">=</span>  <span class="bp">self</span><span class="o">.</span><span class="n">_makeDtypes</span><span class="p">(</span><span class="n">fields</span><span class="p">,</span> <span class="n">asFloat</span><span class="p">,</span> <span class="n">withGPS</span><span class="p">)</span>

    <span class="n">numPointRecords</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">getNumPointRecords</span><span class="p">()</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">recEnd</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="n">recStart</span> <span class="o">==</span> <span class="mi">0</span><span class="p">):</span>
      <span class="n">recsToRead</span> <span class="o">=</span> <span class="n">numPointRecords</span>
    <span class="k">elif</span> <span class="p">(</span><span class="n">recEnd</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="n">recStart</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">):</span>
      <span class="n">recsToRead</span> <span class="o">=</span> <span class="n">numPointRecords</span>  <span class="o">-</span> <span class="n">recStart</span>
    <span class="k">else</span><span class="p">:</span>
      <span class="n">recsToRead</span> <span class="o">=</span> <span class="n">recEnd</span>  <span class="o">-</span> <span class="n">recStart</span>

    <span class="n">output_record_count</span> <span class="o">=</span> <span class="n">recsToRead</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">skip</span> <span class="k">else</span> <span class="p">(</span>
      <span class="mi">1</span> <span class="o">+</span> <span class="n">recsToRead</span> <span class="o">/</span> <span class="n">skip</span><span class="p">)</span>

    <span class="c"># Allocate memory to hold all the points according to data type</span>
    <span class="k">if</span> <span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">pointsDtype</span><span class="p">)</span> <span class="ow">is</span> <span class="nb">type</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">)</span> <span class="ow">or</span>
      <span class="nb">isinstance</span><span class="p">(</span><span class="n">pointsDtype</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">)):</span>
      <span class="c"># Create return empty ndarray</span>
      <span class="n">points</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">empty</span><span class="p">(</span><span class="n">shape</span><span class="o">=</span><span class="p">(</span><span class="n">output_record_count</span><span class="p">,),</span>
        <span class="n">dtype</span><span class="o">=</span><span class="n">outputDtype</span><span class="p">)</span>
    <span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">pointsDtype</span><span class="p">)</span> <span class="ow">is</span> <span class="nb">type</span><span class="p">(</span><span class="nb">dict</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">pointsDtype</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
      <span class="c"># Create return empty dictionary</span>
      <span class="n">points</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="k">else</span><span class="p">:</span>
      <span class="c"># Create an empty memory mapped ndarray</span>
      <span class="k">try</span><span class="p">:</span>
        <span class="n">points</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">memmap</span><span class="p">(</span><span class="n">pointsDtype</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">outputDtype</span><span class="p">,</span>
          <span class="n">mode</span><span class="o">=</span><span class="s">&#39;w+&#39;</span><span class="p">,</span> <span class="n">shape</span><span class="o">=</span><span class="n">output_record_count</span><span class="p">)</span>
      <span class="k">except</span> <span class="ne">IOError</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span>
        <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span><span class="s">&quot;Cannot create numpy memory mapped file: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">e</span><span class="p">)</span>
        <span class="k">raise</span> <span class="n">FileCreationError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
      <span class="k">else</span><span class="p">:</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_mapFile</span> <span class="o">=</span> <span class="n">pointsDtype</span>

    <span class="c"># Compute number of record to read at each iteration</span>
    <span class="k">if</span> <span class="n">recsPerChunk</span><span class="p">:</span>
      <span class="c"># We want to read chunkwise:</span>
      <span class="n">recsPerChunk</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">recsToRead</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">recsPerChunk</span><span class="p">))</span>
    <span class="k">else</span><span class="p">:</span>
      <span class="c"># Read &quot;Hole in one&quot;</span>
      <span class="n">recsPerChunk</span> <span class="o">=</span> <span class="n">recsToRead</span>

    <span class="c"># Move file pointer to start of data</span>
    <span class="n">recsize</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">pointDataRecordSize</span><span class="p">()</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">fid</span><span class="p">()</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span>
      <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">getOffsetToPointData</span><span class="p">()</span> <span class="o">+</span> <span class="n">recsize</span> <span class="o">*</span> <span class="n">recStart</span><span class="p">)</span>

    <span class="n">info</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;Reading&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span><span class="o">.</span><span class="n">filename</span><span class="p">())</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span><span class="o">.</span><span class="n">progress</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">info</span><span class="p">)</span>

    <span class="c"># File reading loop, executed once in case nRecs is large enough</span>
    <span class="n">remainingRecords</span> <span class="o">=</span> <span class="n">recsToRead</span>
    <span class="n">numChunks</span> <span class="o">=</span> <span class="mi">0</span> <span class="c"># Number of data chunks read</span>
    <span class="n">totalRecsRead</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">while</span> <span class="n">remainingRecords</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_stopped</span><span class="p">:</span>
      <span class="n">data</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">fromfile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">fid</span><span class="p">(),</span> <span class="n">count</span><span class="o">=</span><span class="n">recsPerChunk</span><span class="p">,</span>
        <span class="n">dtype</span><span class="o">=</span><span class="n">inputDtype</span><span class="p">)</span>
      <span class="n">recsReadThisCunk</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
      <span class="n">numChunks</span> <span class="o">+=</span> <span class="mi">1</span>

      <span class="c"># Apply decimation if set</span>
      <span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="p">[::</span><span class="n">skip</span><span class="p">]</span>
      <span class="c"># Rescale X, Y, Z</span>
      <span class="n">xyz</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_rescaleXYZ</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">offsets</span><span class="p">,</span> <span class="n">asFloat</span><span class="p">)</span>
      <span class="c"># Move data chunk into points</span>
      <span class="n">points</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data2points</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">totalRecsRead</span><span class="p">,</span> <span class="n">xyz</span><span class="p">,</span> <span class="n">points</span><span class="p">)</span>
      <span class="c"># Save number of records actually read</span>
      <span class="n">totalRecsRead</span> <span class="o">+=</span> <span class="n">recsReadThisCunk</span>
      <span class="n">remainingRecords</span> <span class="o">-=</span> <span class="n">recsReadThisCunk</span>

      <span class="c"># Adjust recsPerChunk</span>
      <span class="n">recsPerChunk</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">recsPerChunk</span><span class="p">,</span> <span class="n">remainingRecords</span><span class="p">)</span>

      <span class="n">progress</span> <span class="o">=</span> <span class="mf">1.</span> <span class="o">*</span> <span class="n">totalRecsRead</span> <span class="o">/</span> <span class="n">numPointRecords</span>
      <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span><span class="o">.</span><span class="n">progress</span><span class="p">(</span><span class="n">progress</span><span class="p">,</span> <span class="n">info</span><span class="p">)</span>

    <span class="bp">self</span><span class="o">.</span><span class="n">_removedRecords</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">if</span> <span class="n">unique</span><span class="p">:</span>
      <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">pointsDtype</span><span class="p">)</span> <span class="ow">is</span> <span class="nb">type</span><span class="p">(</span><span class="nb">dict</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">pointsDtype</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
        <span class="k">raise</span> <span class="n">UnimplementedException</span><span class="p">(</span>
          <span class="s">&quot;Cannot remove duplicate records from dict objects.&quot;</span><span class="p">)</span>
      <span class="k">else</span><span class="p">:</span>
        <span class="c"># Remove duplicates</span>
        <span class="n">points</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">unique</span><span class="p">(</span><span class="n">points</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_removedRecords</span> <span class="o">=</span> <span class="n">totalRecsRead</span> <span class="o">-</span> <span class="n">points</span><span class="p">[</span><span class="s">&#39;X&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
    <span class="k">return</span> <span class="n">points</span>
</div>
<div class="viewcode-block" id="PointDataRecords.removedRecords"><a class="viewcode-back" href="../../ALASpy.html#ALASpy.pointDataRecords.PointDataRecords.removedRecords">[docs]</a>  <span class="k">def</span> <span class="nf">removedRecords</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Return the number of removed records while reading in case of</span>
<span class="sd">        duplicate records</span>

<span class="sd">      :returns: number of removed records while reading</span>
<span class="sd">      :rtype: int or None</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_removedRecords</span>

<span class="c">#-------------------------------------------------------------------------------</span></div>
<div class="viewcode-block" id="PointDataRecords.write"><a class="viewcode-back" href="../../ALASpy.html#ALASpy.pointDataRecords.PointDataRecords.write">[docs]</a>  <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">points</span><span class="p">,</span> <span class="n">recStart</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">recEnd</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">skip</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">recsPerChunk</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
    <span class="n">offsets</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Write LAS Header, Variable Length Records **AND** binary record(s)</span>
<span class="sd">        to file and leave file **CLOSED**</span>

<span class="sd">      :param points: either</span>
<span class="sd">                     Recarray, Memory Mapped Array or dict object containing</span>
<span class="sd">                     LASER points</span>
<span class="sd">                     or</span>
<span class="sd">                     list or tuple of the same objects.</span>
<span class="sd">      :type  points: numpy.ndarray, numpy.memmap or dict</span>
<span class="sd">      :param recStart: Record number to start from (default 0)</span>
<span class="sd">      :type  recStart: integer</span>
<span class="sd">      :param recEnd: Last record to write,  (default is -1, the number of</span>
<span class="sd">                     records in the `points` object)</span>
<span class="sd">      :type  recEnd: integer</span>
<span class="sd">      :param skip: Integer number of records to skip while writing.</span>
<span class="sd">                   Resample output so that the number of points written</span>
<span class="sd">                   is equal to (num of points) / skip (default None)</span>
<span class="sd">      :type  skip: integer</span>
<span class="sd">      :param recsPerChunk: Write file in recsPerChunk chunks (default None)</span>
<span class="sd">                          (Useful with large datasets)</span>
<span class="sd">      :type  recsPerChunk: integer</span>
<span class="sd">      :param offsets: offsets tuple to apply to x, y, z data (default None)</span>
<span class="sd">      :type  offsets: tuple</span>
<span class="sd">      :raises: :class:`~ALASpy.lasExceptions.InvalidPointDataFormatID`,</span>
<span class="sd">               :class:`ValueError`</span>

<span class="sd">      .. warning:: Leaves file **CLOSED**</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="c"># Check for mandatory fields</span>
    <span class="n">checkForMandatoryFields</span><span class="p">(</span><span class="n">points</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">recEnd</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
      <span class="c"># End is last point of dataset</span>
      <span class="n">recEnd</span> <span class="o">=</span> <span class="n">points</span><span class="p">[</span><span class="s">&#39;X&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">size</span>

    <span class="c"># Sanity check</span>
    <span class="k">if</span> <span class="n">recEnd</span> <span class="o">&lt;</span> <span class="n">recStart</span><span class="p">:</span>
      <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s">&quot;start (</span><span class="si">%d</span><span class="s">) must be less than recend (</span><span class="si">%d</span><span class="s">)&quot;</span> <span class="o">%</span>
        <span class="p">(</span><span class="n">recStart</span><span class="p">,</span> <span class="n">recEnd</span><span class="p">))</span>

    <span class="c"># Compute number of output records</span>
    <span class="n">recsToWrite</span> <span class="o">=</span> <span class="n">points</span><span class="p">[</span><span class="s">&#39;X&#39;</span><span class="p">][</span>
      <span class="n">recStart</span><span class="p">:</span> <span class="n">recEnd</span><span class="p">:</span> <span class="n">skip</span><span class="p">]</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>

    <span class="c"># Compute number of record to write at each iteration</span>
    <span class="k">if</span> <span class="n">recsPerChunk</span><span class="p">:</span>
      <span class="c"># We want to write chunkwise:</span>
      <span class="n">recsPerChunk</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">min</span><span class="p">(</span><span class="n">recsToWrite</span><span class="p">,</span> <span class="n">recsPerChunk</span><span class="p">))</span>
    <span class="k">else</span><span class="p">:</span>
      <span class="c"># Write &quot;Hole in one&quot;</span>
      <span class="n">recsPerChunk</span> <span class="o">=</span> <span class="n">recsToWrite</span>

    <span class="k">if</span> <span class="n">hasGPSTime</span><span class="p">(</span><span class="n">points</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span>
      <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">getPointDataFormatID</span><span class="p">()</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">)):</span>
      <span class="k">raise</span> <span class="n">InvalidPointDataFormatID</span><span class="p">(</span>
        <span class="s">&quot;PointDataFormatID is </span><span class="si">%d</span><span class="s"> but dataset *HAS* GPS Time info.&quot;</span> <span class="o">%</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">getPointDataFormatID</span><span class="p">())</span>

    <span class="c"># Create output structure</span>
    <span class="n">lasDtype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">pointDataRecordDtype</span><span class="p">()</span>
    <span class="n">nonMandatoryFields</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">lasDtype</span><span class="o">.</span><span class="n">names</span><span class="p">)</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="s">&#39;XYZ&#39;</span><span class="p">))</span>
    <span class="n">output</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span><span class="n">shape</span><span class="o">=</span><span class="n">recsToWrite</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">lasDtype</span><span class="p">)</span>

    <span class="n">min_xyz</span> <span class="o">=</span> <span class="p">[</span><span class="n">points</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">min</span><span class="p">()</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="s">&quot;XYZ&quot;</span><span class="p">]</span>
    <span class="n">max_xyz</span> <span class="o">=</span> <span class="p">[</span><span class="n">points</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">max</span><span class="p">()</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="s">&quot;XYZ&quot;</span><span class="p">]</span>

    <span class="c"># Set offsets in Header</span>
    <span class="k">if</span> <span class="n">offsets</span> <span class="o">==</span> <span class="bp">None</span><span class="p">:</span>
      <span class="n">offsets</span> <span class="o">=</span> <span class="n">min_xyz</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">setOffsets</span><span class="p">(</span><span class="o">*</span><span class="n">offsets</span><span class="p">)</span>

    <span class="n">scaleFactors</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">scaleFactors</span><span class="p">()</span>
    <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">f</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="s">&quot;XYZ&quot;</span><span class="p">):</span>
      <span class="n">output</span><span class="p">[</span><span class="n">f</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">round</span><span class="p">((</span>
        <span class="n">points</span><span class="p">[</span><span class="n">f</span><span class="p">][</span><span class="n">recStart</span><span class="p">:</span> <span class="n">recEnd</span><span class="p">:</span> <span class="n">skip</span><span class="p">]</span> <span class="o">-</span> <span class="n">offsets</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">/</span>
        <span class="n">scaleFactors</span><span class="p">[</span><span class="n">i</span><span class="p">]))</span><span class="o">.</span><span class="n">flatten</span><span class="p">()</span>

    <span class="c"># NON MANDATORY FIELDS:</span>
    <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">nonMandatoryFields</span><span class="p">:</span>
      <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">points</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">points</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
          <span class="n">output</span><span class="p">[</span><span class="n">f</span><span class="p">]</span> <span class="o">=</span> <span class="n">points</span><span class="p">[</span><span class="n">f</span><span class="p">][</span><span class="n">recStart</span><span class="p">:</span><span class="n">recEnd</span><span class="p">:</span><span class="n">skip</span><span class="p">]</span>
      <span class="k">else</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">points</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">names</span><span class="p">:</span>
          <span class="n">output</span><span class="p">[</span><span class="n">f</span><span class="p">]</span> <span class="o">=</span> <span class="n">points</span><span class="p">[</span><span class="n">f</span><span class="p">][</span><span class="n">recStart</span><span class="p">:</span><span class="n">recEnd</span><span class="p">:</span><span class="n">skip</span><span class="p">]</span>

    <span class="c"># Update Header</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">setRanges</span><span class="p">(</span>
      <span class="n">sumLists</span><span class="p">(</span><span class="n">min_xyz</span><span class="p">,</span> <span class="n">offsets</span><span class="p">),</span> <span class="n">sumLists</span><span class="p">(</span><span class="n">max_xyz</span><span class="p">,</span> <span class="n">offsets</span><span class="p">))</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">setNumPointRecords</span><span class="p">(</span><span class="n">output</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>

    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">getPointDataFormatID</span><span class="p">()</span> <span class="o">&lt;</span> <span class="mi">6</span><span class="p">:</span>
      <span class="n">byteData</span> <span class="o">=</span> <span class="n">output</span><span class="p">[</span><span class="s">&#39;AByte&#39;</span><span class="p">][</span><span class="n">recStart</span><span class="p">:</span><span class="n">recEnd</span><span class="p">:</span><span class="n">skip</span><span class="p">]</span>
    <span class="k">else</span><span class="p">:</span>
      <span class="n">byteData</span> <span class="o">=</span> <span class="n">output</span><span class="p">[</span><span class="s">&#39;2Bytes&#39;</span><span class="p">][</span><span class="n">recStart</span><span class="p">:</span><span class="n">recEnd</span><span class="p">:</span><span class="n">skip</span><span class="p">]</span>
    <span class="c"># Count points by return number</span>
    <span class="n">returnNumbers</span> <span class="o">=</span> <span class="n">PointDataRecord</span><span class="o">.</span><span class="n">getReturnNumber</span><span class="p">(</span><span class="n">byteData</span><span class="p">)</span>
    <span class="n">numPoints</span> <span class="o">=</span> <span class="p">[(</span><span class="n">returnNumbers</span> <span class="o">==</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">sum</span><span class="p">()</span>
      <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">dummy</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">getNumPointsByReturn</span><span class="p">())]</span>
    <span class="c"># Update header</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">setNumPointsByReturn</span><span class="p">(</span><span class="n">numPoints</span><span class="p">)</span>

    <span class="c">#######################################</span>
    <span class="c"># RIEN NE VA PLUS! Write Header and VLR</span>
    <span class="c">#######################################</span>
    <span class="n">info</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;Writing&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span><span class="o">.</span><span class="n">filename</span><span class="p">())</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span><span class="o">.</span><span class="n">progress</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">info</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_header</span><span class="o">.</span><span class="n">write</span><span class="p">()</span>

    <span class="c"># File writing loop, executed once in case nRecs is large enough</span>
    <span class="n">remainingRecords</span> <span class="o">=</span> <span class="n">recsToWrite</span>

    <span class="n">recsWritten</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">while</span> <span class="n">remainingRecords</span><span class="p">:</span>
      <span class="c"># Adjust recsPerChunk</span>
      <span class="n">recsPerChunk</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">recsPerChunk</span><span class="p">,</span> <span class="n">remainingRecords</span><span class="p">)</span>
      <span class="n">start</span> <span class="o">=</span> <span class="n">recsToWrite</span> <span class="o">-</span> <span class="n">remainingRecords</span>
      <span class="n">end</span> <span class="o">=</span> <span class="n">start</span> <span class="o">+</span> <span class="n">recsPerChunk</span>
      <span class="n">output</span><span class="p">[</span><span class="n">start</span><span class="p">:</span> <span class="n">end</span><span class="p">]</span><span class="o">.</span><span class="n">tofile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_parent</span><span class="o">.</span><span class="n">fid</span><span class="p">())</span>
      <span class="c"># Save number of records actually read</span>
      <span class="n">recsWritten</span> <span class="o">+=</span> <span class="n">recsPerChunk</span>
      <span class="n">remainingRecords</span> <span class="o">-=</span> <span class="n">recsPerChunk</span>
      <span class="c"># Memory mapped array?</span>
      <span class="n">progress</span> <span class="o">=</span> <span class="mf">1.</span> <span class="o">*</span> <span class="n">recsWritten</span> <span class="o">/</span> <span class="n">recsToWrite</span>
      <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span><span class="o">.</span><span class="n">progress</span><span class="p">(</span><span class="n">progress</span><span class="p">,</span> <span class="n">info</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span><span class="o">.</span><span class="n">fid</span><span class="p">()</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>

<span class="c">#-------------------------------------------------------------------------------</span></div>
<div class="viewcode-block" id="PointDataRecords.mapFile"><a class="viewcode-back" href="../../ALASpy.html#ALASpy.pointDataRecords.PointDataRecords.mapFile">[docs]</a>  <span class="k">def</span> <span class="nf">mapFile</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Return name of Memory Mapped file or None</span>

<span class="sd">      :return: Name of Memory Mapped file</span>
<span class="sd">      :rtype: String or None</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_mapFile</span></div></div>
</pre></div>

          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <p class="logo"><a href="../../index.html">
              <img class="logo" src="../../_static/ogs.png" alt="Logo"/>
            </a></p>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="../../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li><a href="../../index.html">ALASpy 0.1.1 documentation</a> &raquo;</li>
          <li><a href="../index.html" >Module code</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
        &copy; Copyright 2012, Roberto Vidmar, Nicola Creati.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
    </div>
  </body>
</html>